package org.ims.inv.web.action.flow;

import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.ims.inv.model.flow.ModelFlowBase;
import org.ims.inv.model.flow.ModelFlowDef;
import org.ims.inv.model.flow.ModelFlowTemplate;
import org.ims.inv.model.flow.confer.ModelFlowConfer;
import org.ims.inv.model.project.ModelProjectProcess;
import org.ims.inv.model.system.ModelAppRole;
import org.ims.inv.service.project.ServiceProjectProcess;
import org.springframework.beans.BeanUtils;

import cn.trymore.core.exception.ServiceException;
import cn.trymore.core.log.LogAnnotation;
import cn.trymore.core.util.UtilCollection;
import cn.trymore.core.util.UtilString;

/**
 * Action: 工作流模板
 * 
 * @author Jeccy.Zhao
 *
 */
public class FlowDefTemplateAction
extends FlowBaseAction
{
	/**
	 * The LOGGER
	 */
	private static final Logger LOGGER = Logger.getLogger(FlowDefTemplateAction.class);
	
	/**
	 * Service of project process
	 */
	private ServiceProjectProcess serviceProjectProcess;
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 流程模板页面
	 */
	public ActionForward pageFlowTemplateIndex (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		return mapping.findForward("page.flow.def.tpl.index");
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 流程模板弹框
	 */
	public ActionForward dialogFlowTemplatePage (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		try
		{
			String entityId = request.getParameter("id");
			if (UtilString.isNotEmpty(entityId))
			{
				if (this.isObjectIdValid(entityId))
				{
					ModelFlowTemplate entity = this.serviceWorkFlow.getServiceFlowTemplate().get(entityId);
					request.setAttribute("entity", entity);
				}
				else
				{
					return ajaxPrint(response, getErrorCallback("节点数据ID不合法!"));
				}
			}
			else
			{
				String defId = request.getParameter("defId");
				if (!UtilString.isNotEmpty(defId) && this.isObjectIdValid(defId))
				{
					return ajaxPrint(response, getErrorCallback("模板数据ID未给定或者不合法!"));
				}
				else
				{
					request.setAttribute("defId", defId);
				}
			}
		
			request.setAttribute("allRoles", this.getAllRoles());
			
			// 获取前置过会审批节点
			request.setAttribute("conferFlows", serviceWorkFlow.getServiceFlowConfer().getAll());
			
		}
		catch (Exception e)
		{
			LOGGER.error("Exception raised when loading dialog page", e);
			return ajaxPrint(response, getErrorCallback("数据加载失败,原因:" + e.getMessage()));
		}
		
		return mapping.findForward("dialog.flow.def.tpl");
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 保存流程定义
	 */
	@LogAnnotation(description="审批节点新增或更新, `${nodeTitle}`",type="流程设置")
	public ActionForward actionSaveFlowTemplate (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		try
		{
			String defId = request.getParameter("defId");
			if (UtilString.isNotEmpty(defId) && this.isObjectIdValid(defId))
			{
				ModelFlowTemplate formEntity = (ModelFlowTemplate)form;
				ModelFlowTemplate entity = formEntity;
				
				boolean isActionEdit = this.isObjectIdValid(formEntity.getId());
				
				if (isActionEdit)
				{
					// 编辑
					entity = this.serviceWorkFlow.getServiceFlowTemplate().get(formEntity.getId());
					if (entity != null)
					{
						BeanUtils.copyProperties(formEntity, entity, 
								new String[] { "flowDef", "sequence", "toAuditRole", "dependedFlow" } );
					}
					else
					{
						return ajaxPrint(response, getErrorCallback("数据实体不存在!"));
					}
				}
				else
				{
					int steps = this.serviceWorkFlow.getAvailableSeqs(defId, ModelFlowBase.SRC_PROCESS_DEF);
					entity.setSequence(steps + 1);
				}
				
				// 设置审批角色
				String roleId = request.getParameter("toAuditRoleId");
				if (this.isObjectIdValid(roleId))
				{
					ModelAppRole role = this.serviceAppRole.get(roleId);
					if (role != null)
					{
						entity.setToAuditRole(role);
					}
					else
					{
						return ajaxPrint(response, getErrorCallback("审批角色不存在!"));
					}
				}
				
				// 设置前置审批
				String dependedFlowId = request.getParameter("dependedFlowId");
				if (UtilString.isNotEmpty(dependedFlowId))
				{
					if (this.isObjectIdValid(dependedFlowId))
					{
						ModelFlowConfer confer = this.serviceWorkFlow.getServiceFlowConfer().get(dependedFlowId);
						if (confer != null)
						{
							entity.setDependedFlow(confer);
						}
						else
						{
							return ajaxPrint(response, getErrorCallback("前置审批节点数据不存在!"));
						}
					}
				}
				else
				{
					entity.setDependedFlow(null);
				}
				
				// 设置归属模板
				ModelFlowDef def = this.serviceWorkFlow.getServiceFlowDefinition().get(defId);
				if (def != null)
				{
					entity.setFlowDef(def);
				}
				else
				{
					return ajaxPrint(response, getErrorCallback("数据模板不存在!"));
				}
				
				// 保存
				this.serviceWorkFlow.getServiceFlowTemplate().save(entity);
				
				// 更新关联
				def.appendTemplateDate(entity);
				this.serviceWorkFlow.getServiceFlowDefinition().save(def);
				
				// 更新正在进行的审核表中的前置审批信息
				List<ModelProjectProcess> runningProcess = this.serviceProjectProcess.getProcessByNodeKey(entity.getNodeKey());
				if (UtilCollection.isNotEmpty(runningProcess))
				{
					for (ModelProjectProcess process : runningProcess)
					{
						if (process.getDependedFlowAuditStatus() == null 
								|| process.getDependedFlow() == null)
						{
							process.setDependedFlow(entity.getDependedFlow());
							this.serviceProjectProcess.save(process);
						}
					}
				}
				
				return ajaxPrint(response, 
						getSuccessCallback("数据保存成功.", CALLBACK_TYPE_CLOSE, CURRENT_NAVTABID, null, false));
			}
			else
			{
				return ajaxPrint(response, getErrorCallback("模板数据ID未给定或者不合法!"));
			}
		}
		catch (ServiceException e)
		{
			LOGGER.error("Exception raised when saving data", e);
			return ajaxPrint(response, getErrorCallback("操作失败,原因:" + e.getMessage()));
		}
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 移除流程定义
	 */
	@LogAnnotation(description="审批节点移除, `${id}`",type="流程设置")
	public ActionForward actionRemoveFlowTemplate (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		try
		{
			String entityId = request.getParameter("id");
			if (this.isObjectIdValid(entityId))
			{
				ModelFlowTemplate entity = this.serviceWorkFlow.getServiceFlowTemplate().get(entityId);
				ModelFlowDef def = entity.getFlowDef();
				if (entity != null && def != null)
				{
					// 更新关联
					Iterator<ModelFlowTemplate> itors = def.getTemplates().iterator();
					while (itors.hasNext())
					{
						ModelFlowTemplate template = itors.next();
						if (template.getId().equals(entity.getId()))
						{
							itors.remove();
							break;
						}
					}
					
					// 更新模板数据
					this.serviceWorkFlow.getServiceFlowDefinition().save(def);
					
					// 更新sequence序列图
					this.serviceWorkFlow.refreshFlowSequenceMap(def.getId());
					
					return ajaxPrint(response, 
						getSuccessCallbackAndReloadCurrent("数据删除成功."));
				}
				else
				{
					return ajaxPrint(response, getErrorCallback("数据实体不存在!"));
				}
			}
			else
			{
				return ajaxPrint(response, getErrorCallback("数据ID不合法!"));
			}
		}
		catch (ServiceException e)
		{
			LOGGER.error("Exception raised when removing data", e);
			return ajaxPrint(response, getErrorCallback("数据删除失败,原因:" + e.getMessage()));
		}
		
	}
	
	public static Logger getLogger()
	{
		return LOGGER;
	}

	public void setServiceProjectProcess(ServiceProjectProcess serviceProjectProcess)
	{
		this.serviceProjectProcess = serviceProjectProcess;
	}

	public ServiceProjectProcess getServiceProjectProcess()
	{
		return serviceProjectProcess;
	}
	
}
